package com.bj58.analysis.tools.common;


import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 字符串工具类
 * 
 * @author nicolas
 * 
 */
public class StringHelper {
	public static String urlDecode(String content, String charset) throws UnsupportedEncodingException {
		if (content != null) {
			return URLDecoder.decode(content, charset);
		} else {
			return "";
		}
	}

	public static String urlEncode(String content, String charset) throws UnsupportedEncodingException {
		return URLEncoder.encode(content, charset);
	}

	public static String encode(String source, String from, String to) throws UnsupportedEncodingException {
		byte[] bts;
		bts = source.getBytes(from);
		return new String(bts, to);
	}

	public static String parseCharacterEncoding(String contentType) {
		if (contentType == null)
			return (null);
		int start = contentType.indexOf("charset=");
		if (start < 0)
			return (null);
		String encoding = contentType.substring(start + 8);
		int end = encoding.indexOf(';');
		if (end >= 0)
			encoding = encoding.substring(0, end);
		encoding = encoding.trim();
		if ((encoding.length() > 2) && (encoding.startsWith("\"")) && (encoding.endsWith("\"")))
			encoding = encoding.substring(1, encoding.length() - 1);
		return (encoding.trim());

	}

	public static boolean isEmpty(String str) {
		return (str == null) || (str.equals(""));
	}

	private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
			'e', 'f' };

	public static String toHexString(byte[] buf) {
		return toHexString(buf, null, Integer.MAX_VALUE);
	}

	public static String toHexString(byte[] buf, String sep, int lineLen) {
		if (buf == null)
			return null;
		if (lineLen <= 0)
			lineLen = Integer.MAX_VALUE;
		// StringBuffer res = new StringBuffer(buf.length * 2);
		StringBuilder res = new StringBuilder(buf.length * 2);
		for (int i = 0; i < buf.length; i++) {
			int b = buf[i];
			res.append(HEX_DIGITS[(b >> 4) & 0xf]);
			res.append(HEX_DIGITS[b & 0xf]);
			if (i > 0 && (i % lineLen) == 0)
				res.append('\n');
			else if (sep != null && i < lineLen - 1)
				res.append(sep);
		}
		return res.toString();
	}

	private static final int charToNibble(char c) {
		if (c >= '0' && c <= '9') {
			return c - '0';
		} else if (c >= 'a' && c <= 'f') {
			return 0xa + (c - 'a');
		} else if (c >= 'A' && c <= 'F') {
			return 0xA + (c - 'A');
		} else {
			return -1;
		}
	}

	public static byte[] fromHexString(String text) {
		text = text.trim();
		if (text.length() % 2 != 0)
			text = "0" + text;
		int resLen = text.length() / 2;
		int loNibble, hiNibble;
		byte[] res = new byte[resLen];
		for (int i = 0; i < resLen; i++) {
			int j = i << 1;
			hiNibble = charToNibble(text.charAt(j));
			loNibble = charToNibble(text.charAt(j + 1));
			if (loNibble == -1 || hiNibble == -1)
				return null;
			res[i] = (byte) (hiNibble << 4 | loNibble);
		}
		return res;
	}

	public static String join(String[] arr, String split) {
		if (arr != null && arr.length > 0) {
			StringBuilder stringBuilder = new StringBuilder();
			for (String s : arr) {
				stringBuilder.append(s).append(split);
			}
			stringBuilder.delete(stringBuilder.length() - split.length(), stringBuilder.length());
			return stringBuilder.toString();
		} else {
			return "";
		}
	}

	public static String join(Object[] arr, String split) {
		if (arr != null && arr.length > 0) {
			StringBuilder stringBuilder = new StringBuilder();
			for (Object s : arr) {
				stringBuilder.append(String.valueOf(s)).append(split);
			}
			stringBuilder.delete(stringBuilder.length() - split.length(), stringBuilder.length());
			return stringBuilder.toString();
		} else {
			return "";
		}
	}

	public static Properties parseProperties(String data, String split) {
		Properties properties = new Properties();
		if (!isEmpty(split) && !isEmpty(data)) {
			for (String dd : data.split(split)) {
				String[] d = dd.split("=");
				if (d.length == 2) {
					properties.put(d[0], d[1]);
				}
			}
		}
		return properties;
	}

	/**
	 * 去标签处理 create by yanjr at 2010-08-06 11:20
	 */
	public static String splitAndFilterString(String input) {
		if (input == null || input.trim().equals("")) {
			return "";
		}
		// 去掉所有html元素
		String str = input.replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "");
		str = str.replaceAll("[(/>)<]", "");
		return str;

	}
	
	
	public static String fromMapToHiveString(Map<String,String> fromMap,String CollItemDelim,String MapKeyDelim){
		// 把map转化成字符串，后两个参数是多个键值对之间的分隔符，还有map的kv之间的分隔符
		StringBuffer result = new StringBuffer("");
		
		for (String s:fromMap.keySet()){
			// System.out.println(s);
			// System.out.println(fromMap.get(s));
			if ( ! "".equals(result.toString()) ){
				// 字符串非�?添加多个键�?对之间的分隔
				result.append(CollItemDelim);
			}
			result.append(s);
			result.append(MapKeyDelim);
			result.append(fromMap.get(s));
			
		}
		
		return result.toString();
	}
	
	public static String fromMapToHiveString(Map<String,String> fromMap){
		// 把map转化成字符串，供hive查询使用，分隔符使用hive的默认分隔符
		StringBuffer result = new StringBuffer("");
		
		for (String s:fromMap.keySet()){
			// System.out.println(s);
			// System.out.println(fromMap.get(s));
			if ( ! "".equals(result.toString()) ){
				// 字符串非�?添加多个键�?对之间的分隔
				result.append(HiveDelimiter.CollItemDelim);
			}
			result.append(s);
			result.append(HiveDelimiter.MapKeyDelim);
			result.append(fromMap.get(s));
			
		}
		
		return result.toString();
	}
	
	/*
	 *  功能：字符串转化成Map第一个参数是要转的字符串，第二个参数是多个字段间分隔符，第三个参数是KV之间的分隔符
	 */
	
	public static Map<String,String> fromStringToMap(String line, String CollItemDelim , String MapKeyDelim){
		Map<String,String> result = new HashMap<String,String>();
		
		// 先去掉中文字符干扰
		line = line.replace("，", ",").replace("｛", "{")
				.replace("｝", "}").replace("：", ":").replace("‘", "'").replace("’", "'");
		// 如果传入的行是以大括号开头结束的，则去掉，否则不去掉
		if( line.startsWith("{") && line.endsWith("}") ){
			// 不用replace方法的原因是防止替换K/V里的大括号
			line = line.substring( 1 );
			line = line.substring(0,line.length()-1);
		}
		
		int i = 0;
		while ( i>-1 ){
			i = line.indexOf(CollItemDelim);
			if (i>-1){
				// 先要看截到的是不是一个完整的KV。防止V里面有分隔符
				// 问题：如果没有单引号做字段结束的标志，该怎么办？？？？？目前没有办法
				try{
					// 这里是看截取的是不是一个完整的K/V。判断方法是看V的开始符号和结束符号，如果以单引号开始必须以单引号结束，以大括号开始的必须以大括号结束，才是一个完整的K/V
					// tmp是从头截取的第一个K/V的V。
					String tmp = line.substring( line.indexOf(MapKeyDelim)+1 , i);
					if ( tmp.startsWith("'")){
						while(  ! tmp.endsWith("'") ){
							i = line.indexOf(CollItemDelim, i+1) ;
							// 再次截取的时候，由于只是看结尾，所以这里不用只截V了
							tmp = line.substring(0, i);
						}
					}else if ( tmp.startsWith("{")){
						while(  ! tmp.endsWith("}") ){
							i = line.indexOf(CollItemDelim, i+1) ;
							tmp = line.substring(0, i);
						}
					}
				}catch (Exception e){
				}
			}
			String firstpart = "";
			try{
				firstpart = line.substring(0, i);
				line = line.substring(i+1);
				// System.out.println(firstpart+"-----"+line);
			}catch (Exception e){
				firstpart = line;
			}
			String key = "";
			String value = "";
			String kv = firstpart;
			try{
				// 如果k以引号开头结束，那么v也要去掉引号，否则就不用
				if ( kv.split(MapKeyDelim)[0].startsWith("'") && kv.split(MapKeyDelim)[0].endsWith("'") ){
					key = kv.split(MapKeyDelim)[0].split("'")[1].trim();
					// 防止最后一个KV的V为空
					if (! kv.endsWith(MapKeyDelim)) {
						// 去掉开头结束的单引号
						value = kv.split(MapKeyDelim,2)[1];
						value = value.substring(1);
						value = value.substring(0, value.length()-1 );
					}
				}
				else {
					key = kv.split(MapKeyDelim)[0].trim();
					// 防止最后一个KV的V为空
					if (! kv.endsWith(MapKeyDelim)) {
						value = kv.split(MapKeyDelim,2)[1].trim();
					}
				}
			}catch (Exception e){
				try{
					key = kv.split(MapKeyDelim)[0].trim();
					value = kv.split(MapKeyDelim,2)[1].trim();
				}catch (Exception e1){
					
				}
			}
			result.put(key, value);
		}
		return result;
	}
}
